﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Krile.Kernel.Data;
using System.Windows.Forms;
using Krile.Kernel.Bridges;
using Krile.Forms.MainForm;
using Krile.Kernel.WindowsEx;

namespace Krile.Data
{
    static internal class DefaultKeyAssigns
    {
        internal static void SelectAbove(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetSelectStatus(SearchTarget.SelectTargets.Above);
            form.EnsureVisible();
        }

        internal static void SelectBelow(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetSelectStatus(SearchTarget.SelectTargets.Below);
            form.EnsureVisible();
        }

        internal static void SelectNewAbove(IForm form, Status selected, Keys pressed)
        {
            if (!((IFormEx)form).SetSelectStatus(SearchTarget.SelectTargets.AboveNew))
            {
                MessageBoxEx.Show(Lang.Msg.KeyAssign_NothingNewAbove, Lang.Msg.KeyAssign_NothingNewAbove_Caption,
                      MessageBoxEx.MessageBoxExButtons.Close, MessageBoxEx.MessageBoxExIcon.Information);
            }
            else
                form.EnsureVisible();
        }

        internal static void SelectNewBelow(IForm form, Status selected, Keys pressed)
        {
            if (!((IFormEx)form).SetSelectStatus(SearchTarget.SelectTargets.BelowNew))
            {
                MessageBoxEx.Show( Lang.Msg.KeyAssign_NothingNewBelow, Lang.Msg.KeyAssign_NothingNewBelow_Caption,
                     MessageBoxEx.MessageBoxExButtons.Close, MessageBoxEx.MessageBoxExIcon.Information);
            }
            else
                form.EnsureVisible();
        }

        internal static void ScrollAbove(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetScrollState(SearchTarget.SelectTargets.Above);
        }

        internal static void ScrollBelow(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetScrollState(SearchTarget.SelectTargets.Below);
        }

        internal static void ScrollTop(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetScrollState(SearchTarget.SelectTargets.Top);
        }

        internal static void ScrollEnd(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetScrollState(SearchTarget.SelectTargets.End);
        }

        internal static void SelectNewestStatus(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetSelectStatus(SearchTarget.SelectTargets.Newest);
            form.EnsureVisible();
        }

        internal static void OpenPostbox(IForm form, Status selected, Keys pressed)
        {
            Core.FormManager.MainForm.SetPostboxState(true);
        }

        internal static void ClosePostbox(IForm form, Status selected, Keys pressed)
        {
            Core.FormManager.MainForm.SetPostboxState(false);
        }

        internal static void TogglePostbox(IForm form, Status selected, Keys pressed)
        {
            Core.FormManager.MainForm.SetPostboxState(!Core.Config.State.ShowPostBox);
        }

        internal static void FocusToTimeline(IForm form, Status selected, Keys pressed)
        {
            Core.FormManager.MainForm.FocusToTimeline();
        }

        internal static void OpenSearchBar(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetSearchbarVisible(true);
        }

        internal static void CloseSearchBar(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetSearchbarVisible(false);
        }

        internal static void ToggleSearchBar(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetSearchbarVisible(!((IFormEx)form).SearchbarVisible);
        }

        internal static void ShowConfig(IForm form, Status selected, Keys pressed)
        {
            if (Core.FormManager.MainForm.Visible)
                Core.FormManager.MainForm.ShowConfig();
            else
                using (var cog = new Forms.ConfigForm.Config())
                {
                    cog.ShowDialog();
                }
        }

        internal static void AddNewTab(IForm form, Status selected, Keys pressed)
        {
            Core.FormManager.MainForm.CreateTab();
        }

        internal static void AddQuickTab(IForm form, Status selected, Keys pressed)
        {
            Core.FormManager.MainForm.CreateQuickTab();
        }

        internal static void ExtractThisUser(IForm form, Status selected, Keys pressed)
        {
            ExtractThisUser(form, selected);
        }

        internal static void ExtractThisUser(IForm form, Status selected)
        {
            if (form != null && selected != null)
            {
                ((IFormEx)form).AddInheritedTabAutoFormat("@" + selected.User.Id,
                    new[] { new Data.UserIdSearchData(selected.User.Id) });
            }
        }

        internal static void ExtractThisUserStrict(IForm form, Status selected, Keys pressed)
        {
            if (form != null && selected != null)
            {
                ((IFormEx)form).AddInheritedTabAutoFormat("@" + selected.User.Id,
                    new SearchData[] { new Data.UserIdSearchData(selected.User.Id), new Data.ServiceIdSearchData(selected.ParentService.Id) });
            }
        }

        internal static void ExtractThisService(IForm form, Status selected, Keys pressed)
        {
            ExtractThisService(form, selected);
        }

        internal static void ExtractThisService(IForm form, Status selected)
        {
            if (form != null && selected != null)
            {
                ((IFormEx)form).AddInheritedTabAutoFormat("Service " + selected.ParentService.Name,
                    new[] { new Data.ServiceIdSearchData(selected.ParentService.Id) });
            }
        }

        internal static void ExtractThisPostsReply(IForm form, Status selected, Keys pressed)
        {
            if (form != null && selected != null)
            {
                ((IFormEx)form).AddInheritedTabAutoFormat("in reply to " + selected.Id,
                    new SearchData[] { new Data.ServiceIdSearchData(selected.ParentService.Id), new Data.ReplyIdSearchData(selected.Id) });
            }
        }

        internal static void ExtractConversation(IForm form, Status selected, Keys pressed)
        {
            if (form != null && selected != null)
            {
                if (selected.ReplyData == null || String.IsNullOrEmpty(selected.ReplyData.ReplyToUserId))
                {
                    MessageBoxEx.Show(Lang.Msg.KeyAssign_NoReply_Context, Lang.Msg.KeyAssign_NoReply, Lang.Msg.KeyAssign_NoReply_Caption,
                         MessageBoxEx.MessageBoxExButtons.Close, MessageBoxEx.MessageBoxExIcon.Error);
                    return;
                }
                ((IFormEx)form).AddInheritedTabAutoFormat("Talk:@" + selected.User.Id + " & @" + selected.ReplyData.ReplyToUserId,
                    new[]{
                    new SearchDataCluster(new []{
                        new SearchDataCluster(new SearchData[]{
                            new Data.UserIdSearchData(selected.User.Id),
                            new Data.ReplyUserIdSearchData(selected.ReplyData.ReplyToUserId)}),
                        new SearchDataCluster(new SearchData[]{
                            new Data.UserIdSearchData(selected.ReplyData.ReplyToUserId),
                            new Data.ReplyUserIdSearchData(selected.User.Id)})
                    }){ UseOrMatch = true}});
            }
        }

        internal static void EditSelectedTab(IForm form, Status selected, Keys pressed)
        {
            var item = ((IFormEx)form).TabControl.SelectedItem as Forms.MainForm.Controls.XTab.XTabTLItem;
            if (item != null)
                item.EditThis(null, null);
        }

        internal static void CloseSelectedTab(IForm form, Status selected, Keys pressed)
        {
            var item = ((IFormEx)form).TabControl.SelectedItem as Forms.MainForm.Controls.XTab.XTabTLItem;
            if (item != null)
                if (item.TabData.Locked)
                    MessageBoxEx.Show(Lang.Msg.KeyAssign_TabLocked_Context, Lang.Msg.KeyAssign_TabLocked, Lang.Msg.KeyAssign_TabLocked_Caption,
                         MessageBoxEx.MessageBoxExButtons.Close, MessageBoxEx.MessageBoxExIcon.Warning);
                else
                    item.CloseThis(null, null);
        }

        internal static void ToggleTabLock(IForm form, Status selected, Keys pressed)
        {
            var item = ((IFormEx)form).TabControl.SelectedItem as Forms.MainForm.Controls.XTab.XTabTLItem;
            if (item != null)
                item.ToggleLock(null, null);
        }

        internal static void SetGlobalTL(IForm form, Status selected, Keys pressed)
        {
            Core.FormManager.MainForm.SetRecvGTL(null, null);
        }

        internal static void RefreshTimeline(IForm form, Status selected, Keys pressed)
        {
            foreach (var svc in Core.PluginManager.GetServiceEnumerator())
            {
                svc.ParentAgent.Status.ReceiveStatuses();
            }
        }

        internal static void SetAlreadyReadedAll(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetReadedAll();
        }

        internal static void ToggleUnlock(IForm form, Status selected, Keys pressed)
        {
            if (Core.FormManager.MainForm != null)
                Core.FormManager.MainForm.ToggleUnlock(null, null);
        }

        internal static void ToggleTopmost(IForm form, Status selected, Keys pressed)
        {
            Core.FormManager.MainForm.ToggleTopMost(null, null);
        }
    
        internal static void SelectRightTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectNextTab();
        }

        internal static void SelectLeftTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectPrevTab();
        }

        internal static void Select1stTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(0);
        }

        internal static void Select2ndTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(1);
        }

        internal static void Select3rdTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(2);
        }

        internal static void Select4thTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(3);
        }

        internal static void Select5thTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(4);
        }

        internal static void Select6thTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(5);
        }

        internal static void Select7thTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(6);
        }

        internal static void Select8thTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(7);
        }

        internal static void Select9thTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(8);
        }

        internal static void Select10thTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(9);
        }

        internal static void Select11thTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(10);
        }

        internal static void Select12thTab(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).TabControl.SelectTab(11);
        }

        internal static void DeselectTimeline(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).SetSelectStatus(SearchTarget.SelectTargets.Deselect);
        }

        internal static void EnsureVisibleSelectedStatus(IForm form, Status selected, Keys pressed)
        {
            form.EnsureVisible();
        }

        internal static void EnsureVisibleTop(IForm form, Status selected, Keys pressed)
        {
            ((IFormEx)form).EnsureVisibleTop();
        }

        internal static void ShowUserPage(IForm form, Status selected, Keys pressed)
        {
            if (selected == null) return;
            Subsystem.CommonOperation.CallBrowser(selected.User.ProfileUri.OriginalString);
        }

        internal static void ShowStatusPage(IForm form, Status selected, Keys pressed)
        {
            if (selected == null) return;
            if (selected.StatusPage == null || String.IsNullOrEmpty(selected.StatusPage.OriginalString))
                MessageBoxEx.Show(Lang.Msg.KeyAssign_StatusPageOpenError_Context, Lang.Msg.KeyAssign_StatusPageOpenError, Lang.Msg.KeyAssign_StatusPageOpenError_Caption,
                     MessageBoxEx.MessageBoxExButtons.Close, MessageBoxEx.MessageBoxExIcon.Error);
            else
                Subsystem.CommonOperation.CallBrowser(selected.StatusPage.OriginalString);
        }

        internal static void JumpInReplyTo(IForm form, Status selected, Keys pressed)
        {
            if (selected == null || selected.ReplyData == null) return;
            var uid = selected.ReplyData.ReplyOnClick();
            if (uid > 0)
            {
                if (!((IFormEx)form).SelectStatusByUID(uid, true))
                    MessageBoxEx.Show(Lang.Msg.KeyAssign_JumpToReplyError, Lang.Msg.KeyAssign_JumpToReplyError_Caption,
                    MessageBoxEx.MessageBoxExButtons.Close, MessageBoxEx.MessageBoxExIcon.Warning);
            }
            form.EnsureVisible();
        }

        internal static void CopyStatus(IForm form, Status selected, Keys pressed)
        {
            if (selected == null) return;
            Clipboard.SetText(selected.Text.Original);
            Core.FormManager.MainForm.SetStatusText(Lang.StatusText.Copied, 3);
        }

        internal static void CopyUserID(IForm form, Status selected, Keys pressed)
        {
            if (selected == null) return;
            Clipboard.SetText(selected.User.Id);
            Core.FormManager.MainForm.SetStatusText(Lang.StatusText.Copied, 3);
        }

        internal static void DefaultReply(IForm form, Status selected, Keys pressed)
        {
            if (selected == null) return;
            if (!selected.ParentAgent.Status.AutoCreateReplyOperationTriggers ||
                selected.Unreplyable) return;
            Core.FormManager.MainForm.InputControlManager.SetReplyTo(selected.UID);
        }

        internal static void DefaultFav(IForm form, Status selected, Keys pressed)
        {
            if (selected == null) return;
            if (!selected.ParentAgent.Status.AutoCreateFavOperationTriggers ||
            (!Core.Config.Timeline.AllowFavMyself && selected.ParentAgent.IsMasterId(selected.User.Id)) ||
            selected.Unfavorable) return;

            Action<IForm> act = new Action<IForm>((f) =>
            {
                Core.FormManager.MainForm.SetStatusText(Lang.StatusText.Favouring);
                if (f != null)
                    f.RefreshTL(false);
                var or = selected.ParentAgent.Status.SetFavorite(selected.UID, !selected.Favored);
                if (or.Succeeded)
                {
                    selected.Favored = !selected.Favored;
                }
                else
                {
                    Subsystem.Debugger.AddReport(new Krile.Kernel.Bridges.DebugReport("Fav operation was failed at " + selected.UID.ToString()));
                    Core.FormManager.MainForm.SetStatusText(Lang.StatusText.FavError, 3);
                }
                if (f != null)
                    f.RefreshTL(true);
                Core.FormManager.MainForm.SetStatusText(Lang.StatusText.Favored, 3);
                Core.StatusManager.UpdateStatus(new[] { selected.UID });
            });
            act.BeginInvoke(form, (iar) => ((Action<IForm>)iar.AsyncState).EndInvoke(iar), act);
        }

        internal static void RestoreClosedTab(IForm form, Status selected, Keys pressed)
        {
            Core.FormManager.MainForm.RestoreClosedTab();
        }

        internal static void RestartKrile(IForm form, Status selected, Keys pressed)
        {
            if (MessageBoxEx.Show( Lang.Msg.KeyAssign_RestartKrile, Lang.Msg.KeyAssign_RestartKrile_Caption,
                 MessageBoxEx.MessageBoxExButtons.YesNo, MessageBoxEx.MessageBoxExIcon.Warning) == MessageBoxEx.DialogResultEx.Yes)
            {
                Core.ExitApp(true);
            }
        }

        internal static void KillKrile(IForm form, Status selected, Keys pressed)
        {
            Core.ExitApp(false);
        }

        internal static void NextWindow(IForm form, Status selected, Keys pressed)
        {
            if (Core.FormManager.MainForm.MdiChildren == null || Core.FormManager.MainForm.MdiChildren.Length == 0)
                return;
            bool next = false;
            foreach (var f in Core.FormManager.MainForm.MdiChildren)
            {
                if (next)
                {
                    f.Activate();
                    return;
                }
                if (Core.FormManager.MainForm.ActiveMdiChild == f)
                    next = true;
            }
            Core.FormManager.MainForm.MdiChildren[0].Activate();
        }

        internal static void PrevWindow(IForm form, Status selected, Keys pressed)
        {
            if (Core.FormManager.MainForm.MdiChildren == null || Core.FormManager.MainForm.MdiChildren.Length == 0)
                return;
            Form prev = null;
            foreach (var f in Core.FormManager.MainForm.MdiChildren)
            {
                if (Core.FormManager.MainForm.ActiveMdiChild == f)
                {
                    if (prev != null)
                    {
                        prev.Activate();
                        return;
                    }
                }
                prev = f;
            }
            prev.Activate();
        }
    }
}
